package com.runjian.rundo.iot.agent.iec104;

import java.net.InetAddress;
import java.net.UnknownHostException;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.env.Environment;
import org.springframework.scheduling.annotation.EnableAsync;

/**
 * Iec104启动程序
 * IEC 60870-5-104协议中的握手流程，通常包括以下几个步骤：
 *
 * 1. **首次握手（U帧）**：这是链路建立阶段，主站发送激活传输启动命令（StartDT），从站收到命令后，需要确认激活传输启动。具体报文格式为：
 *    - 主站发送：`68 04 07 00 00 00`
 *    - 从站响应：`68 04 0B 00 00 00`
 *
 * 2. **总召唤**：初始化后，主站可以发送总召唤命令（General Interrogation），从站收到总召唤命令后，会发送确认帧，并开始传输所有当前的监控数据，如遥测值和遥信状态。总召唤的报文格式为：
 *    - 主站发送总召唤：`68 0E 00 00 00 00 64 01 06 00 01 00 00 00 00 14`
 *    - 从站响应总召唤确认：`68 0E 02 00 02 00 64 01 07 00 01 00 00 00 00 14`
 *
 * 3. **传输数据**：从站开始将所有当前的监控数据发送回主站，这些数据以ASDU的形式发送。
 *
 * 4. **总召唤结束**：从站发送一个总召唤结束标志，表明所有数据已发送完毕。这个ASDU类型标识为100，原因码为10（结束）。
 *
 * 5. **测试帧**：如果主站超过一定时间没有下发报文或从站也没有上送任何报文，则双方都可以按频率发送U帧，测试帧，以确保链路的连通性。测试帧的报文格式为：
 *    - 主站发送测试帧：`68 04 43 00 00 00`
 *    - 从站响应测试帧确认：`68 04 83 00 00 00`
 *
 * 6. **遥控**：主站可以发送遥控命令来控制从站的设备状态。遥控过程可能包括预置、执行、撤销等步骤，涉及到的报文类型包括遥控预置、遥控反校、遥控执行、执行确认、遥控撤销和撤销确认等。
 *
 * @author CaoQingHua
 */
@EnableAsync
@SpringBootApplication(scanBasePackages = {"com.runjian.rundo"})
public class IotAgentIec104Application {

    public static void main(String[] args) throws UnknownHostException {
        ConfigurableApplicationContext application = SpringApplication.run(IotAgentIec104Application.class, args);
        Environment env = application.getEnvironment();
        String ip = InetAddress.getLocalHost().getHostAddress();
        String port = env.getProperty("server.port");
        String id = application.getId();

        System.out.print("----------------------------------------------------------\n\t" + id + " is running! Access URLs:\n\t"
            + "Local:    http://localhost:" + port + "\n\t" + "External: http://" + ip + ":" + port + "\n\t"
            + "----------------------------------------------------------\n");
    }
}